/*
 * Copyright (C) 2007-2012 by XDEV Software, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 3.0 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
package xdev.ui;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.EventListener;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;

import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JWindow;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.NumberFormatter;

import xdev.ui.text.TextFormat;


public class DatePopup
{
	static Map<Object, DatePopup>	instances	= new Hashtable();
	

	public static DatePopup getInstance(Component owner)
	{
		Window window = SwingUtilities.getWindowAncestor(owner);
		if(window == null)
		{
			window = JOptionPane.getRootFrame();
		}
		
		DatePopup popup = instances.get(window);
		if(popup == null)
		{
			popup = new DatePopup(window);
			instances.put(window,popup);
			
			window.addComponentListener(new ComponentAdapter()
			{
				@Override
				public void componentHidden(ComponentEvent e)
				{
					Component c = e.getComponent();
					instances.remove(c);
					c.removeComponentListener(this);
				}
			});
		}
		
		return popup;
	}
	
	private static DatePopupCustomizer	defaultCustomizer;
	static
	{
		defaultCustomizer = new DatePopupCustomizer()
		{
			@Override
			public int getMinYear()
			{
				return 1900;
			}
			

			@Override
			public int getMaxYear()
			{
				return 3000;
			}
		};
	}
	

	public static void setDefaultCustomizer(DatePopupCustomizer defaultCustomizer)
	{
		if(defaultCustomizer == null)
		{
			throw new IllegalArgumentException("defaultCustomizer can't be null");
		}
		
		DatePopup.defaultCustomizer = defaultCustomizer;
	}
	

	public static DatePopupCustomizer getDefaultCustomizer()
	{
		return defaultCustomizer;
	}
	
	private final static Dimension	dateLabelSize	= new Dimension(25,18);
	private Calendar				calendar;
	private JPanel					contentPane, pnlDate, pnlTime;
	private JComboBox				cmbMonth, cmbYear;
	private ArrowButton				cmdPrevious, cmdNext;
	private JSpinner				spinHour, spinMinute, spinSecond;
	private DayHeader[]				dayHeader;
	private DayButton[]				dayButton;
	private String[]				monthString;
	private JButton					cmdNow, cmdOK;
	private JWindow					window;
	private DatePopupOwner			owner;
	private TextFormat				textFormat;
	private Locale					locale;
	private DateFormat				dayFormat, yearFormat;
	private boolean					fireChanged		= true, noteComboChange = true;
	

	private DatePopup(Window owner)
	{
		calendar = Calendar.getInstance();
		
		int monthCount = calendar.getMaximum(Calendar.MONTH) + 1;
		monthString = new String[monthCount];
		Month[] months = new Month[monthCount];
		for(int i = 0; i < monthCount; i++)
		{
			monthString[i] = "";
			months[i] = new Month(i);
		}
		
		cmbMonth = new JComboBox(months);
		cmbMonth.setMaximumRowCount(monthCount);
		cmbMonth.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				calendar.set(Calendar.MONTH,((Month)cmbMonth.getSelectedItem()).month);
				
				if(noteComboChange)
				{
					fill(true);
				}
			}
		});
		
		cmbYear = new JComboBox();
		cmbYear.setMaximumRowCount(monthCount);
		cmbYear.setRenderer(new YearComboRenderer());
		cmbYear.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				calendar.set(Calendar.YEAR,(Integer)cmbYear.getSelectedItem());
				
				if(noteComboChange)
				{
					fill(true);
				}
			}
		});
		
		cmdPrevious = new ArrowButton(SwingConstants.LEFT)
		{
			@Override
			public void setCoords(int x, int y)
			{
				xp[0] = x;
				xp[1] = x + 5;
				xp[2] = x + 5;
				yp[0] = y + 5;
				yp[1] = y;
				yp[2] = y + 10;
			}
		};
		cmdPrevious.setBorder(BorderFactory.createEmptyBorder(0,1,0,5));
		cmdPrevious.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				noteComboChange = false;
				
				int i = cmbMonth.getSelectedIndex();
				if(i == 0)
				{
					cmbMonth.setSelectedIndex(cmbMonth.getModel().getSize() - 1);
					cmbYear.setSelectedIndex(Math.max(0,cmbYear.getSelectedIndex() - 1));
				}
				else
				{
					cmbMonth.setSelectedIndex(i - 1);
				}
				
				noteComboChange = true;
				fill(true);
			}
		});
		
		cmdNext = new ArrowButton(SwingConstants.RIGHT)
		{
			@Override
			public void setCoords(int x, int y)
			{
				xp[0] = x + 5;
				xp[1] = x;
				xp[2] = x;
				yp[0] = y + 5;
				yp[1] = y;
				yp[2] = y + 10;
			}
		};
		cmdNext.setBorder(BorderFactory.createEmptyBorder(0,3,0,10));
		cmdNext.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				noteComboChange = false;
				
				int i = cmbMonth.getSelectedIndex();
				if(i == cmbMonth.getModel().getSize() - 1)
				{
					cmbMonth.setSelectedIndex(0);
					cmbYear.setSelectedIndex(Math.min(cmbYear.getModel().getSize() - 1,
							cmbYear.getSelectedIndex() + 1));
				}
				else
				{
					cmbMonth.setSelectedIndex(i + 1);
				}
				
				noteComboChange = true;
				fill(true);
			}
		});
		
		JPanel pnlDay = new JPanel(null);
		pnlDay.setOpaque(false);
		Dimension size = new Dimension(dateLabelSize.width * 7 + 1,dateLabelSize.height * 7 + 1);
		pnlDay.setPreferredSize(size);
		pnlDay.setSize(size);
		
		dayHeader = new DayHeader[7];
		for(int x = 0; x < 7; x++)
		{
			dayHeader[x] = new DayHeader("00");
			dayHeader[x].setLocation(x * dateLabelSize.width,0);
			pnlDay.add(dayHeader[x]);
		}
		
		int i = 0;
		dayButton = new DayButton[42];
		
		for(int y = 1; y <= 6; y++)
		{
			for(int x = 0; x < 7; x++, i++)
			{
				dayButton[i] = new DayButton();
				dayButton[i].setLocation(x * dateLabelSize.width,y * dateLabelSize.height);
				pnlDay.add(dayButton[i]);
			}
		}
		
		spinHour = new JSpinner(new SpinnerNumberModel(0,0,23,1));
		spinHour.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent e)
			{
				if(fireChanged)
				{
					calendar.set(Calendar.HOUR_OF_DAY,(Integer)spinHour.getValue());
				}
			}
		});
		timizeSpinnerEditor(spinHour);
		
		spinMinute = new JSpinner(new SpinnerNumberModel(0,0,59,1));
		spinMinute.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent e)
			{
				if(fireChanged)
				{
					calendar.set(Calendar.MINUTE,(Integer)spinMinute.getValue());
				}
			}
		});
		timizeSpinnerEditor(spinMinute);
		
		spinSecond = new JSpinner(new SpinnerNumberModel(0,0,59,1));
		spinSecond.addChangeListener(new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent e)
			{
				if(fireChanged)
				{
					calendar.set(Calendar.SECOND,(Integer)spinSecond.getValue());
				}
			}
		});
		timizeSpinnerEditor(spinSecond);
		
		cmdNow = new JButton(UIResourceBundle.getString("datechooser.now"));
		cmdNow.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				setTime(new Date());
			}
		});
		
		cmdOK = new JButton(UIManager.getString("OptionPane.okButtonText"));
		cmdOK.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				hidePopup(true);
			}
		});
		
		JPanel pnlMonth = new JPanel(new BorderLayout());
		pnlMonth.setOpaque(false);
		pnlMonth.add(cmdPrevious,BorderLayout.WEST);
		pnlMonth.add(cmbMonth,BorderLayout.CENTER);
		pnlMonth.add(cmdNext,BorderLayout.EAST);
		
		JPanel pnlNorth = new JPanel(new BorderLayout());
		pnlNorth.setOpaque(false);
		pnlNorth.add(pnlMonth,BorderLayout.CENTER);
		pnlNorth.add(cmbYear,BorderLayout.EAST);
		
		pnlDate = new JPanel(new BorderLayout(0,10));
		pnlDate.setOpaque(false);
		pnlDate.add(pnlNorth,BorderLayout.NORTH);
		pnlDate.add(pnlDay,BorderLayout.CENTER);
		
		JPanel pnlHour = new JPanel(new BorderLayout());
		pnlHour.setOpaque(false);
		pnlHour.add(spinHour,BorderLayout.CENTER);
		pnlHour.add(new JLabel(" : "),BorderLayout.EAST);
		
		JPanel pnlMinute = new JPanel(new BorderLayout());
		pnlMinute.setOpaque(false);
		pnlMinute.add(spinMinute,BorderLayout.CENTER);
		pnlMinute.add(new JLabel(" : "),BorderLayout.EAST);
		
		JPanel pnlTimeSetter = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
		pnlTimeSetter.setOpaque(false);
		pnlTimeSetter.add(pnlHour);
		pnlTimeSetter.add(pnlMinute);
		pnlTimeSetter.add(spinSecond);
		
		pnlTime = new JPanel(new BorderLayout());
		pnlTime.setOpaque(false);
		pnlTime.add(new JLabel(UIResourceBundle.getString("datechooser.time")),BorderLayout.CENTER);
		pnlTime.add(pnlTimeSetter,BorderLayout.EAST);
		
		JPanel pnlButtons = new JPanel(new GridLayout(1,2,5,0));
		pnlButtons.setOpaque(false);
		pnlButtons.add(cmdNow);
		pnlButtons.add(cmdOK);
		
		JPanel pnlDummy = new JPanel();
		pnlDummy.setOpaque(false);
		
		JPanel pnlCmd = new JPanel(new BorderLayout());
		pnlCmd.setOpaque(false);
		pnlCmd.add(pnlDummy,BorderLayout.CENTER);
		pnlCmd.add(pnlButtons,BorderLayout.EAST);
		
		JPanel pnlSouth = new JPanel(new BorderLayout(0,20));
		pnlSouth.setOpaque(false);
		pnlSouth.add(pnlTime,BorderLayout.NORTH);
		pnlSouth.add(pnlCmd,BorderLayout.CENTER);
		
		contentPane = new JPanel(new BorderLayout(0,10));
		contentPane.setBackground(Color.white);
		contentPane.setBorder(BorderFactory.createCompoundBorder(
				UIManager.getBorder("PopupMenu.border"),
				BorderFactory.createEmptyBorder(10,10,10,10)));
		contentPane.add(pnlDate,BorderLayout.CENTER);
		contentPane.add(pnlSouth,BorderLayout.SOUTH);
		
		window = new JWindow(owner);
		window.setContentPane(contentPane);
		window.setFocusableWindowState(false);
		
		locale = Locale.getDefault();
		dayFormat = new SimpleDateFormat("d",locale);
		yearFormat = new SimpleDateFormat("yyyy",locale);
	}
	

	private void timizeSpinnerEditor(JSpinner spinner)
	{
		JSpinner.NumberEditor editor = (JSpinner.NumberEditor)spinner.getEditor();
		((NumberFormatter)editor.getTextField().getFormatter()).setFormat(new DecimalFormat("00"));
	}
	

	private void setCustomizer(DatePopupCustomizer customizer)
	{
		if(customizer == null)
		{
			customizer = defaultCustomizer;
		}
		
		int minYear = customizer.getMinYear();
		int maxYear = customizer.getMaxYear();
		cmbYear.setModel(new YearComboBoxModel(minYear,maxYear));
	}
	

	public DatePopupOwner getOwner()
	{
		return owner;
	}
	

	public void showPopup(DatePopupOwner owner)
	{
		setOwner(owner);
		
		Component cpn = owner.getComponentForDatePopup();
		Point p = new Point(0,cpn.getHeight() + 1);
		SwingUtilities.convertPointToScreen(p,cpn);
		
		Rectangle place = window.getGraphicsConfiguration().getBounds();
		Rectangle r = new Rectangle(p,window.getSize());
		
		if(r.y + r.height > place.y + place.height)
		{
			p.y -= cpn.getHeight() + window.getHeight() + 1;
		}
		
		if(r.x + r.width > place.x + place.width)
		{
			p.x = place.x + place.width - r.width;
		}
		
		Date d = null;
		try
		{
			d = textFormat.parseDate(owner.getText());
		}
		catch(Exception e)
		{
			d = new Date();
		}
		setTime(d);
		
		window.setLocation(p);
		window.setVisible(true);
	}
	

	private void setOwner(DatePopupOwner owner)
	{
		this.owner = owner;
		
		textFormat = owner.getTextFormat();
		locale = textFormat.getLocale();
		dayFormat = new SimpleDateFormat("d",locale);
		yearFormat = new SimpleDateFormat("yyyy",locale);
		
		Calendar tempCal = Calendar.getInstance();
		SimpleDateFormat monthFormat = new SimpleDateFormat("MMMM",locale);
		for(int i = 0; i < 12; i++)
		{
			tempCal.set(1999,i,1);
			monthString[i] = monthFormat.format(tempCal.getTime());
		}
		
		pnlDate.setVisible(textFormat.hasDate());
		pnlTime.setVisible(textFormat.hasTime());
		
		tempCal.set(1999,0,1);
		while(tempCal.get(Calendar.DAY_OF_WEEK) != calendar.getFirstDayOfWeek())
		{
			tempCal.add(Calendar.DATE,1);
		}
		
		SimpleDateFormat weekdayFormat = new SimpleDateFormat("E",locale);
		for(int x = 0; x < 7; x++)
		{
			dayHeader[x].setText(weekdayFormat.format(tempCal.getTime()));
			tempCal.roll(Calendar.DATE,true);
		}
		
		setCustomizer(owner.getDatePopupCustomizer());
		
		Dimension size = contentPane.getPreferredSize();
		Insets insets = window.getInsets();
		Dimension ps = new Dimension(size.width + insets.left + insets.right,size.height
				+ insets.top + insets.bottom);
		window.setSize(ps);
	}
	

	private void setTime(Date d)
	{
		calendar.setTime(d);
		
		fill(false);
	}
	

	private void fill(boolean onlyDays)
	{
		fireChanged = false;
		
		int month = calendar.get(Calendar.MONTH);
		int year = calendar.get(Calendar.YEAR);
		
		if(!onlyDays)
		{
			cmbMonth.setSelectedIndex(month);
			cmbYear.setSelectedItem(year);
		}
		
		int tmpDate = calendar.get(Calendar.DATE);
		calendar.set(Calendar.DATE,1);
		int start = calendar.get(Calendar.DAY_OF_WEEK) - calendar.getFirstDayOfWeek();
		if(start < 0)
		{
			start = 7 + start;
		}
		calendar.set(Calendar.DATE,tmpDate);
		
		int end = start + calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		for(int i = 0; i < start; i++)
		{
			dayButton[i].setDay(-1);
		}
		
		for(int i = start, day = 1; i < end; i++, day++)
		{
			dayButton[i].setDay(day);
		}
		
		for(int i = end; i < dayButton.length; i++)
		{
			dayButton[i].setDay(-1);
		}
		
		spinHour.setValue(new Integer(calendar.get(Calendar.HOUR_OF_DAY)));
		spinMinute.setValue(new Integer(calendar.get(Calendar.MINUTE)));
		spinSecond.setValue(new Integer(calendar.get(Calendar.SECOND)));
		
		fireChanged = true;
	}
	

	public boolean isVisible()
	{
		return window.isVisible();
	}
	

	public void hidePopup()
	{
		window.setVisible(false);
	}
	

	private void hidePopup(boolean fire)
	{
		owner.hideDatePopup();
		
		if(fire)
		{
			try
			{
				owner.setText(textFormat.format(calendar.getTime()));
			}
			catch(Exception e)
			{
			}
		}
	}
	

	private void checkDaySelection()
	{
		for(int i = 0; i < dayButton.length; i++)
		{
			dayButton[i].checkSelection();
		}
	}
	


	private class DayHeader extends JLabel
	{
		DayHeader(String caption)
		{
			super(caption);
			
			setHorizontalAlignment(CENTER);
			setSize(dateLabelSize.width + 1,dateLabelSize.height + 1);
			setOpaque(true);
			setBackground(UIManager.getColor("TableHeader.background"));
			setForeground(UIManager.getColor("TableHeader.foreground"));
			setBorder(BorderFactory.createLineBorder(UIManager.getColor("Table.gridColor"),1));
		}
	}
	


	private class DayButton extends JLabel implements MouseListener
	{
		int			day;
		boolean		selected	= false;
		Calendar	tempCal		= Calendar.getInstance();
		

		DayButton()
		{
			super("");
			
			setHorizontalAlignment(CENTER);
			setSize(dateLabelSize.width + 1,dateLabelSize.height + 1);
			setOpaque(true);
			setBackground(Color.white);
			setForeground(Color.black);
			setBorder(BorderFactory.createLineBorder(UIManager.getColor("Table.gridColor"),1));
			
			addMouseListener(this);
		}
		

		void setDay(int day)
		{
			this.day = day;
			checkSelection();
			
			if(day == -1)
			{
				setText("");
			}
			else
			{
				tempCal.setTimeInMillis(calendar.getTimeInMillis());
				tempCal.set(Calendar.DAY_OF_MONTH,day);
				setText(dayFormat.format(tempCal.getTime()));
			}
		}
		

		void checkSelection()
		{
			selected = calendar.get(Calendar.DAY_OF_MONTH) == day;
			setBackground(selected ? UIManager.getColor("Table.selectionBackground") : UIManager
					.getColor("Table.background"));
			setForeground(selected ? UIManager.getColor("Table.selectionForeground") : UIManager
					.getColor("Table.foreground"));
			Font f = UIManager.getFont("Label.font");
			setFont(selected ? f.deriveFont(Font.BOLD) : f);
		}
		

		public void mousePressed(MouseEvent e)
		{
			if(day != -1)
			{
				calendar.set(Calendar.DAY_OF_MONTH,day);
				checkDaySelection();
				if(e.getClickCount() > 1)
				{
					hidePopup(true);
				}
			}
		}
		

		public void mouseExited(MouseEvent e)
		{
			if(day != -1 && !selected)
			{
				setBackground(Color.white);
				setForeground(Color.black);
			}
		}
		

		public void mouseEntered(MouseEvent e)
		{
			if(day != -1 && !selected)
			{
				setBackground(Color.black);
				setForeground(Color.white);
			}
		}
		

		public void mouseClicked(MouseEvent e)
		{
		}
		

		public void mouseReleased(MouseEvent e)
		{
		}
	}
	


	private abstract class ArrowButton extends JLabel implements Icon, MouseListener
	{
		int	direction;
		boolean	mouseOver	= false, mouseDown = false;
		int[]	xp			= new int[3];
		int[]	yp			= new int[3];
		

		ArrowButton(int direction)
		{
			super();
			this.direction = direction;
			setIcon(this);
			addMouseListener(this);
		}
		

		void addActionListener(ActionListener al)
		{
			listenerList.add(ActionListener.class,al);
		}
		

		public int getIconWidth()
		{
			return 5;
		}
		

		public int getIconHeight()
		{
			return 9;
		}
		

		public void paintIcon(Component c, Graphics g0, int x, int y)
		{
			if(mouseDown)
			{
				x += direction == SwingConstants.LEFT ? -1 : 1;
			}
			
			setCoords(x,y);
			
			Graphics2D g = (Graphics2D)g0;
			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
			
			if(mouseOver)
			{
				g.setColor(Color.white);
				g.fillPolygon(xp,yp,3);
				
				g.setColor(Color.black);
				g.drawPolygon(xp,yp,3);
			}
			else
			{
				g.setColor(Color.black);
				g.fillPolygon(xp,yp,3);
			}
		}
		

		abstract void setCoords(int x, int y);
		

		public void mouseEntered(MouseEvent e)
		{
			mouseOver = true;
			repaint();
		}
		

		public void mouseExited(MouseEvent e)
		{
			mouseOver = false;
			repaint();
		}
		

		public void mousePressed(MouseEvent e)
		{
			mouseDown = true;
			repaint();
		}
		

		public void mouseReleased(MouseEvent e)
		{
			mouseDown = false;
			repaint();
		}
		

		public void mouseClicked(MouseEvent e)
		{
			EventListener[] el = listenerList.getListeners(ActionListener.class);
			for(int i = 0; i < el.length; i++)
			{
				((ActionListener)el[i]).actionPerformed(new ActionEvent(this,0,""));
			}
		}
	}
	


	private static class YearComboBoxModel extends AbstractListModel implements ComboBoxModel
	{
		final int	min, size;
		Object		selectedObject;
		

		YearComboBoxModel(int min, int max)
		{
			this.min = min;
			this.size = max - min + 1;
		}
		

		@Override
		public Object getSelectedItem()
		{
			return selectedObject;
		}
		

		@Override
		public void setSelectedItem(Object anObject)
		{
			if((selectedObject != null && !selectedObject.equals(anObject))
					|| selectedObject == null && anObject != null)
			{
				selectedObject = anObject;
				fireContentsChanged(this,-1,-1);
			}
		}
		

		@Override
		public Object getElementAt(int index)
		{
			return Integer.valueOf(min + index);
		}
		

		@Override
		public int getSize()
		{
			return size;
		}
	}
	


	private class Month
	{
		final int	month;
		

		Month(int month)
		{
			this.month = month;
		}
		

		@Override
		public String toString()
		{
			return monthString[month];
		}
	}
	


	private class YearComboRenderer extends DefaultListCellRenderer
	{
		final Calendar	cal;
		final Date		date;
		{
			cal = Calendar.getInstance();
			cal.set(2000,0,1);
			date = new Date();
		}
		

		@Override
		public Component getListCellRendererComponent(JList list, Object value, int index,
				boolean isSelected, boolean cellHasFocus)
		{
			if(value instanceof Integer)
			{
				cal.set(Calendar.YEAR,(Integer)value);
				date.setTime(cal.getTimeInMillis());
				value = yearFormat.format(date);
			}
			return super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);
		}
	}
}
